<template>
  <div>
    <canvas class="my-canvas" :id="'myCanvas' + id" :width="cWidth" :height="cHeight"></canvas>
  </div>
</template>
<script>
export default {
  name: 'zlProgress',
  data(){
    return {
      timer:null
    }
  },
  props: {
    canvasConfig: {
      type: Object,
      default: {}
    },
    cWidth: {
      type: Number,
      default: 200
    }, //画布的宽度
    cHeight: {
      type: Number,
      default: 200
    }, //画布的高度
    id:{
      type:String,
      default:''
    }
  },
  watch:{
    canvasConfig:{
      handler(){
        //由于有immediate属性，会导致在服务端立即执行，因此必须判断环境
        if (typeof window !== 'undefined') {
          this.$nextTick(()=>{
            this.draw()
          })
        }
      },
      deep:true,
      immediate:true
    }
  },
  methods: {
    draw() {
      let {
        percent = 0,//进度百分比
        baseColor='',//圆环底色
        coverColor='#34B3FF',//进度颜色
        leadColor='',//进度头部小圆颜色
        leadRadius=0,//进度头部小圆半径
        lineWidth=0,//进度条宽度
        baseLineWidth=0,//底色条宽度
        isAnimation=false,//是否有动画
        sRadian=0,//进度开始角度
      } = this.canvasConfig
      // 
      if (isNaN(+percent) || isNaN(+leadRadius) || isNaN(+lineWidth) || isNaN(+sRadian)) {
        return
      }
      let cWidth = +this.cWidth
      let cHeight = +this.cHeight
    //  将传入变量设置成数字类型
      percent = +percent
      leadRadius=+leadRadius
      lineWidth=+lineWidth
      sRadian=+sRadian
      if (percent < 0 || percent > 100) {
        return
      }
      if (sRadian > 180 || sRadian <= -180) {
        return
      }
      //   获取画布元素
      var canvas = document.getElementById('myCanvas'+this.id)
      let cxt = canvas.getContext('2d')
      let PI = Math.PI
      let sR = (2 * PI * sRadian) / 360 // 默认圆弧的起始点弧度为π/2
      //需要通过动画渲染
      if (isAnimation) {
        var finalRadian = sR + (2 * PI * percent) / 100 // 终点弧度
        var step = (PI + (PI - sR) * 2) / 100 // 一个1%对应的弧度大小
        var text = 0 // 显示的数字
        cxt.clearRect(0, 0, cWidth, cHeight)
        clearInterval(this.timer)
        this.timer=null
        this.timer = setInterval(() => {
          // 清空画布
          cxt.clearRect(0, 0, cWidth, cHeight)
          var endRadian = text * step + sR
          // 进度圆半径
          let progressRadius = leadColor ? cWidth / 2 - leadRadius * 2 : cWidth / 2 - lineWidth / 2
          // 如果传入了轨道圆颜色则画轨道圆
          if (baseColor) {
            this.drawCanvas(cWidth / 2, cHeight / 2, progressRadius, 0, 2 * PI, baseColor, cxt, baseLineWidth)
          }
          // 画进度圆弧
          this.drawCanvas(cWidth / 2, cHeight / 2, progressRadius, sR, endRadian, coverColor, cxt, lineWidth)
          // 红色圆头其实就是一个圆，关键的是找到其圆心，涉及到三角函数知识，自己画个图一看就明了
          var angle = 2 * PI - endRadian // 转换成逆时针方向的弧度（三角函数中的）
          let xPos = Math.cos(angle) * progressRadius + cWidth / 2 // 红色圆 圆心的x坐标
          let yPos = -Math.sin(angle) * progressRadius + cHeight / 2 // 红色圆 圆心的y坐标
          // 画圆头
          if (leadColor) {
            this.drawCanvas(xPos, yPos, leadRadius, 0, 2 * PI, leadColor, cxt, lineWidth)
          }
          text++
          if (endRadian.toFixed(2) >= finalRadian.toFixed(2)) {
            clearInterval(this.timer)
            this.timer=null
          }
        }, 30)
      } else {
        //无动画效果
        let progressRadius = leadColor ? cWidth / 2 - leadRadius * 2 : cWidth / 2 - lineWidth / 2
        // 清空画布
        cxt.clearRect(0, 0, cWidth, cHeight)
        this.drawCanvas(cWidth / 2, cHeight / 2, progressRadius, 0, 2 * PI, baseColor, cxt, baseLineWidth)
        this.drawCanvas(
          cWidth / 2,
          cHeight / 2,
          progressRadius,
          sR,
          sR + (2 * PI * percent) / 100,
          coverColor,
          cxt,
          lineWidth
        )
        if (leadColor) {
          var angle = 2 * PI - (sR + (2 * PI * percent) / 100) // 转换成逆时针方向的弧度（三角函数中的）
          let xPos = Math.cos(angle) * progressRadius + cWidth / 2 // 红色圆 圆心的x坐标
          let yPos = -Math.sin(angle) * progressRadius + cHeight / 2 // 红色圆 圆心的y坐标
          this.drawCanvas(xPos, yPos, leadRadius, 0, 2 * PI, leadColor, cxt, lineWidth)
        }
      }
    },
    drawCanvas(x, y, r, sRadian, eRadian, color, cxt, lineWidth) {
      cxt.beginPath()
      cxt.lineCap = 'round'
      cxt.strokeStyle = color
      cxt.lineWidth = lineWidth
      cxt.arc(x, y, r, sRadian, eRadian, false)
      cxt.stroke()
    }
  },
  mounted() {
  },
  beforeDestroy(){
    if(this.timer){
      clearInterval(this.timer)
      this.timer = null
    }
  }
}
</script>

<style scoped></style>
